package com.newly.center.auth.config;

import com.newly.common.base.constants.AuthConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;

import java.security.KeyPair;

/**
 * oauth2授权服务器
 *
 * @author: guan
 * @date: 2021/06/20/2:09
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    /**
     * 配置授权方式
     */
    /*
        http://localhost:9090/oauth/authorize?response_type=password&client_id=newly-system
        &redirect_uri=http://www.baidu.com&scope=all
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("newly-system")
                .secret(passwordEncoder.encode("newly-password"))
                .scopes("all")
                .authorizedGrantTypes("password")
                .redirectUris("http://www.baidu.com")
                .accessTokenValiditySeconds(RedisKey.TENANT_EXPIRES_TIME_KEY);
    }


    /**
     * 暴露服务
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore())
                .authenticationManager(authenticationManager)
                .accessTokenConverter(jwtAccessTokenConverter());
    }

    /**
     * 要让oauth的token和redis做关联
     */
    @Bean
    public TokenStore tokenStore() {
        JwtTokenStore jwtTokenStore = new JwtTokenStore(jwtAccessTokenConverter());
        return jwtTokenStore;
    }

    /**
     * jwt转换器（转换token）
     */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        // 对称加密
        //jwtAccessTokenConverter.setSigningKey(CommonConstant.JWT_SIGNING_KEY);

        // 非对称加密
        ClassPathResource resource = new ClassPathResource(AuthConstant.JWT_SIGNING_SLL_PRIVATE_FILE_NAME);
        // 私钥和私钥密码得到私钥工厂
        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(resource, AuthConstant.JWT_SIGNING_SLL_PASS.toCharArray());
        // 别名拿到私钥
        KeyPair keyPair = keyStoreKeyFactory.getKeyPair(AuthConstant.JWT_SIGNING_SLL_ALIAS);
        jwtAccessTokenConverter.setKeyPair(keyPair);
        return jwtAccessTokenConverter;
    }

    /**
     * 密码加密
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}
